<?php
	/**
	*	 文件名：viewModel.php
	*    创建人: 杨旭升
	*    创建时间: 2015/2/5
	*    最后修改时间: 2015/2/5
	*    文件功能概述：视图模型
	*/
	class ViewModel{ 

		//保存要渲染到视图的数据
		private $data;
		//private $view;
		private $c;

		//构造函数，加载配置文件
		public function __construct($conf) { 
			$this->c = $conf;
		}

		/**
		*	添加数据
		*/
		public function addData($key, $value) { 
			$this->data[$key] = $value;
		}

		/**
		*	渲染视图
		*/
		public function display($viewName) {

			//检测是否有已经解析的缓存文件
			$runtimeViewFile = $this->c['RUNTIME_PATH'].str_replace('/', '_', $viewName).'.php';
			if(!file_exists($runtimeViewFile)) { 
				//解析
				$this->doParse($viewName);
			}
			if(file_exists($runtimeViewFile)) { 
				//把数据extract到变量表
				if($this->data) {
					extract($this->data);
				}
				$c = $this->c;
				include $runtimeViewFile;
			} else { 
				echo '找不到视图'.$viewName;
			}
			
		}

		/**
		*	执行解析 
		*/
		private function doParse($viewName) { 
			//视图文件的路径
			$viewFile = $this->c['VIEW_PATH'].$viewName.$this->c['TMP_SUFFIX'];

			//如果视图存在，加载数据，显示视图
			if(file_exists($viewFile)) { 

				//获取view页面内容
				$view = file_get_contents($viewFile);

				//解析include
				$includeReg = '/{{include ([A-Za-z0-9]*)}}/';

				$view = preg_replace_callback($includeReg, function($matches) { 
					$fragmentName = $matches[1];
					return $this->doInclude($fragmentName);
				}, $view);

				//处理array
				$arrayReg = '/{{array ([A-Za-z0-9]*) "(.*)"}}/';
				$view = preg_replace_callback($arrayReg, function($matches) { 
					$temp = 
					'<?php
						$xphp_echoStr = \'\';
						foreach($%s as $k => $v) { 
							$xphp_echoStr .= "%s";
						}
						echo $xphp_echoStr;
					?>';
					$arrayName = $matches[1];
					$echoStr = $matches[2];
					//处理echoStr, 把",替换为\"
					$echoStr = str_replace('"', '\"', $echoStr);
					return sprintf($temp, $arrayName, $echoStr);
				}, $view);

				//解析变量
				$varReg = '/{{([A-Za-z0-9]*)}}/';
				$view = preg_replace_callback($varReg, function($matches) { 
					$varName = $matches[1];
					return '<?=$'.$varName.'?>';
				}, $view);

				//解析public
				$publicStr = '__PUBLIC__';
				$view = str_replace($publicStr, $this->c['PUBLIC_PATH'], $view);

				//把解析后的view写入runtime
				file_put_contents($this->c['RUNTIME_PATH'].str_replace('/', '_', $viewName).'.php', $view);
			}
		}

		/**
		*	处理include
		*/
		private function doInclude($fragmentName) { 

			//片段路径
			$fragmentFile = $this->c['FRAGMENT_PATH'].$fragmentName.$this->c['FRAGMENT_SUFFIX'];

			//如果片段存在，加载片段
			if(file_exists($fragmentFile)) { 
				$fragment = file_get_contents($fragmentFile);
				return $fragment;
			} else { 
				return '未找到片段'.$fragmentFile;
			}
		}

	}

?>